! MODULE module_wrf_netcdf

! CONTAINS
!  MODIFY 
!    Deng Liantang 2004.05.09 
!       Add the SELECT case in subroutines get_var_3d_real and 
!       get_var_2d_real 

  SUBROUTINE get_timesteps_cdf(cdfid,n_times,timesteps,debug)
        
  implicit none

  include 'netcdf.inc'

  integer,           intent(in)  ::  cdfid  
  integer,           intent(in)  ::  n_times
  integer,           intent(out) :: timesteps(n_times)
  integer,           intent(in)  :: debug
 
  integer            :: rcode, id_time, time1
  character (len=80) :: varnam
  integer            :: ndims, natts, idims(10) 
  integer            :: istart(10),icount(10), dimids(10)
  integer            :: i, ivtype

  id_time = ncvid( cdfid, 'ITIMESTEP', rcode )

  rcode = nf_inq_var( cdfid, id_time, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for Time ',ndims
  endif

  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), idims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,idims(i)
  enddo

!  get the timesteps
  
  if (n_times .GT. idims(2)) then   
    if (debug .GT. 0) write(6,*) " n_times: ",n_times," Times dimension: ",idims(2)
    stop 'The input n_times mismatch the "time" dimension'
  end if  

  do i=1,n_times  
    istart(1) = 1
    icount(1) = idims(1)
    istart(2) = i
    icount(2) = 1
    rcode = NF_GET_VARA_INT  ( cdfid, id_time,  &
                               istart, icount,    &
                               timesteps(i)          )
    time1 = timesteps(i)
    if(debug .GE. 300) write(6,*) ' time steps of ',i,' is ',time1
  enddo

  END SUBROUTINE get_timesteps_cdf

!--------------------------------------------------------------------

  SUBROUTINE get_times_cdf(cdfid,n_times,times,debug)
        
  implicit none

  include 'netcdf.inc'

  integer,           intent(in)  ::  cdfid  
  integer,           intent(in)  ::  n_times
  character(len=24), intent(out) :: times(n_times)
  integer,           intent(in)  :: debug
 
  integer            :: rcode, id_time
  character (len=80) :: varnam, time1
  integer            :: ndims, natts, idims(10) 
  integer            :: istart(10),icount(10), dimids(10)
  integer            :: i, ivtype

  id_time = ncvid( cdfid, 'Times', rcode )

  rcode = nf_inq_var( cdfid, id_time, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for Time ',ndims
  endif

  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), idims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,idims(i)
  enddo

!  get the times
  
  if (n_times .GT. idims(2)) then   
    if (debug .GT. 0) write(6,*) " n_times: ",n_times," Times dimension: ",idims(2)
    stop 'The input n_times mismatch the "time" dimension'
  end if  

  do i=1,n_times  
    istart(1) = 1
    icount(1) = idims(1)
    istart(2) = i
    icount(2) = 1
    rcode = NF_GET_VARA_TEXT  ( cdfid, id_time,  &
                                istart, icount,    &
                                times(i)          )
    time1 = times(i)
    if(debug .GE. 300) write(6,*) time1(1:idims(1))
  enddo

  if(debug .GE. 200) write(6,*) ' exiting get_times_cdf '

  END SUBROUTINE get_times_cdf

!-------------------------------------------------------------------------------

  SUBROUTINE get_ntimes_cdf(file,ntimes,debug,rcode)
  implicit none

  include 'netcdf.inc'

  character (len=*), intent(in) :: file
  integer, intent(in ) :: debug
  integer, intent(out) :: ntimes
  integer, intent(out) :: rcode

  integer :: cdfid

    cdfid = ncopn(TRIM(file), NCNOWRIT, rcode )
    call get_gl_dims_len_cdf(cdfid,"Time",ntimes,debug)
    call ncclos(cdfid,rcode)
  END SUBROUTINE get_ntimes_cdf

!-------------------------------------------------------------------------------

  SUBROUTINE get_dims_cdf( cdfid, var, dims, ndims, debug )
        
  implicit none

  include 'netcdf.inc'

  integer, intent(in) :: cdfid
  character (len=*), intent(in) :: var
  integer, intent(in ) :: debug
  integer, intent(out), dimension(4) :: dims
  integer, intent(out) :: ndims

  integer  rcode, id_time
  character (len=80) :: varnam, time1
  integer :: natts, istart(10),icount(10), dimids(10)
  integer :: i, ivtype

  id_time = ncvid( cdfid, var, rcode )

  rcode = nf_inq_var( cdfid, id_time, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for ',var,' ',ndims
  endif
  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), dims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,dims(i)
  enddo

  END SUBROUTINE get_dims_cdf

!-------------------------------------------------------------------------------
  SUBROUTINE get_gl_dims_len_cdf(cdfid, dimname, value, debug)
  implicit none 
  include 'netcdf.inc'

  integer, intent(in)   :: cdfid
  character*(*), intent(in) :: dimname 
  integer, intent(out)  :: value 
  integer, intent(in)   :: debug 

  integer               :: dim_id,len_var,rcode 
 
  len_var = len_trim(dimname)
  rcode = nf_inq_dimid(cdfid, dimname(1:len_var),dim_id) 

  rcode = nf_inq_dimlen(cdfid, dim_id,value)
  
  if (debug .GE. 300) write(6,*) ' Dimension ',dimname(1:len_var), ' =' ,value 
   
  END SUBROUTINE get_gl_dims_len_cdf

!-------------------------------------------------------------------------------

  SUBROUTINE get_gl_att_text_cdf( cdfid, att_name, value, debug )
        
  implicit none

  include 'netcdf.inc'

  integer,           intent(in) :: cdfid
  character (len=*), intent(in) :: att_name
  integer,           intent(in) :: debug
  character(len=*),  intent(out):: value

  integer rcode, len_var

  value = ''
  rcode = NF_INQ_ATTLEN(cdfid, nf_global, att_name, len_var)
  rcode = NF_GET_ATT_TEXT(cdfid, nf_global, att_name, value(1:len_var))

  if(debug .GE. 300) write(6,*) ' global attribute ',att_name,' is ',value(1:len_var)

  END SUBROUTINE get_gl_att_text_cdf

!-------------------------------------------------------------------------------

  SUBROUTINE get_gl_att_int_cdf( cdfid, att_name, value, debug )
        
  implicit none

  include 'netcdf.inc'

  integer, intent(in) :: cdfid
  character (len=*), intent(in) :: att_name
  integer, intent(in ) :: debug
  integer, intent(out) :: value

  integer rcode, id_time

  rcode = NF_GET_ATT_INT(cdfid, nf_global, att_name, value )

  if(debug .GE. 300) write(6,*) ' global attribute ',att_name,' is ',value

  END SUBROUTINE get_gl_att_int_cdf

!-------------------------------------------------------------------------------

  SUBROUTINE get_gl_att_real_cdf( cdfid, att_name, value, debug )
        
  implicit none

  include 'netcdf.inc'

  integer           , intent(in) :: cdfid
  character (len=*), intent(in) :: att_name
  integer, intent(in ) :: debug
  real,    intent(out) :: value

  integer  rcode, id_time

  rcode = NF_GET_ATT_REAL(cdfid, nf_global, att_name, value )

  if(debug .GE. 300) write(6,*) ' global attribute ',att_name,' is ',value

  END SUBROUTINE get_gl_att_real_cdf


!--------------------------------------------------------------------

  SUBROUTINE get_var_3d_real_cdf( cdfid, var, data, &
                                  i1, i2, i3, time, debug )
        
  implicit none

  include 'netcdf.inc'

  integer, intent(in)  ::  cdfid, i1, i2, i3, time
  integer, intent(in ) :: debug
  character (len=*), intent(in) :: var
  real, dimension(i1,i2,i3), intent(out) :: data

  integer(1), dimension(i1,i2,i3) :: i1_data
  integer(2), dimension(i1,i2,i3) :: i2_data
  integer,    dimension(i1,i2,i3) :: int_data

  integer  rcode, id_data
  character (len=80) :: varnam, time1
  integer :: ndims, natts, idims(10), istart(10),icount(10), dimids(10)
  integer :: i, ivtype

  id_data = ncvid( cdfid, var, rcode )

  rcode = nf_inq_var( cdfid, id_data, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for ',var,' ',ndims
  endif
  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), idims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,idims(i)
  enddo

!  check the dimensions

   if( (i1 /= idims(1)) .or.  &
       (i2 /= idims(2)) .or.  &
       (i3 /= idims(3)) .or.  &
       (time > idims(4))     )  then

     write(6,*) ' error in 3d_var_real read, dimension problem '
     write(6,*) i1, idims(1)
     write(6,*) i2, idims(2)
     write(6,*) i3, idims(3)
     write(6,*) time, idims(4)
     write(6,*) ' error stop '
     stop

   end if

!  get the data
  
    istart(1) = 1
    icount(1) = i1
    istart(2) = 1
    icount(2) = i2
    istart(3) = 1
    icount(3) = i3
    istart(4) = time
    icount(4) = 1

    SELECT CASE (ivtype) 
    CASE (NF_FLOAT) 
      rcode = NF_GET_VARA_REAL( cdfid,id_data,istart,icount,data)
    CASE (NF_INT1)
      rcode = NF_GET_VARA_INT1( cdfid,id_data,istart,icount,i1_data)
      data = i1_data
    CASE (NF_INT2)
      rcode = NF_GET_VARA_INT2( cdfid,id_data,istart,icount,i2_data)
      data = i2_data
    CASE (NF_INT)
      rcode = NF_GET_VARA_INT( cdfid,id_data,istart,icount,int_data)
      data = int_data
    CASE DEFAULT 
      rcode = -1
      data = 0
    END SELECT 

  END SUBROUTINE get_var_3d_real_cdf

!--------------------------------------------------------------------

  SUBROUTINE get_var_2d_real_cdf( cdfid, var, data, &
                                  i1, i2, time, debug )
        
  implicit none

  include 'netcdf.inc'

  integer, intent(in)  ::  cdfid, i1, i2, time
  integer, intent(in ) :: debug
  character (len=*), intent(in) :: var
  real, dimension(i1,i2), intent(out) :: data

  integer(1), dimension(i1,i2) :: i1_data
  integer(2), dimension(i1,i2) :: i2_data
  integer,    dimension(i1,i2) :: int_data

  integer  rcode, id_data
  character (len=80) :: varnam, time1
  integer :: ndims, natts, idims(10), istart(10),icount(10), dimids(10)
  integer :: i, ivtype

  id_data = ncvid( cdfid, var, rcode )

  rcode = nf_inq_var( cdfid, id_data, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for ',var,' ',ndims
  endif
  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), idims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,idims(i)
  enddo

!  check the dimensions

   if( (i1 /= idims(1)) .or.  &
       (i2 /= idims(2)) .or.  &
       (time > idims(3))     )  then

     write(6,*) ' error in 2d_var_real read, dimension problem '
     write(6,*) i1, idims(1)
     write(6,*) i2, idims(2)
     write(6,*) time, idims(3)
     write(6,*) ' error stop '
     stop

   end if

!  get the data
  
    istart(1) = 1
    icount(1) = i1
    istart(2) = 1
    icount(2) = i2
    istart(3) = time
    icount(3) = 1

    SELECT CASE (ivtype) 
    CASE (NF_FLOAT) 
      rcode = NF_GET_VARA_REAL( cdfid,id_data,istart,icount,data)
    CASE (NF_INT1)
      rcode = NF_GET_VARA_INT1( cdfid,id_data,istart,icount,i1_data)
      data = i1_data
    CASE (NF_INT2)
      rcode = NF_GET_VARA_INT2( cdfid,id_data,istart,icount,i2_data)
      data = i2_data
    CASE (NF_INT)
      rcode = NF_GET_VARA_INT( cdfid,id_data,istart,icount,int_data)
      data = int_data
    CASE DEFAULT 
      rcode = -1
      data = 0
    END SELECT 

  END SUBROUTINE get_var_2d_real_cdf
  
!--------------------------------------------------------------------

  SUBROUTINE get_var_1d_int_cdf( cdfid, var, data, dim1, time, debug )
        
  implicit none

  include 'netcdf.inc'

  integer,                  intent(in)  ::  cdfid, dim1, time
  integer,                  intent(in)  :: debug
  character (len=*),        intent(in)  :: var
  real,    dimension(dim1), intent(out) :: data

  integer              :: rcode, id_data, int_data(dim1)
  character (len=80)   :: varnam, time1
  integer              :: ndims, natts, idims(10), & 
                          istart(10),icount(10), dimids(10)
  integer              :: i, ivtype 

  id_data = ncvid( cdfid, var, rcode )

  rcode = nf_inq_var( cdfid, id_data, varnam, ivtype, ndims, dimids, natts )
  if(debug .GE. 300) then
    write(6,*) ' number of dims for ',var,' ',ndims
  endif
  do i=1,ndims
    rcode = nf_inq_dimlen( cdfid, dimids(i), idims(i) )
    if(debug .GE. 300) write(6,*) ' dimension ',i,idims(i)
  enddo

!  check the dimensions

   if( (dim1 /= idims(1)) .or. (time > idims(2)) )  then

     write(6,*) ' error in 1d_var_int read, dimension problem '
     write(6,*) dim1, idims(1)
     write(6,*) time, idims(2)
     write(6,*) ' error stop '
     stop

   end if

!  get the data
  
    istart(1) = 1
    icount(1) = dim1
    istart(2) = time
    icount(2) = 1

!    call ncvgt( cdfid,id_data,istart,icount,data,rcode)
    rcode = NF_GET_VARA_INT( cdfid,id_data,istart,icount,int_data) 
    data = int_data

  END SUBROUTINE get_var_1d_int_cdf
  
! END MODULE module_wrf_netcdf
